<template>
  <div id="homePage">
    <!-- 搜索框 -->
    <div class="search-bar">
      <div class="search-title">
        <h1>发现精彩瞬间</h1>
        <p class="subtitle">探索和分享你的创意图片</p>
      </div>
      <a-input-search
        v-model:value="searchParams.searchText"
        placeholder="搜索你感兴趣的图片..."
        enter-button="搜索"
        size="large"
        @search="doSearch"
      >
        <template #enterButton>
          <a-button type="primary" size="large">
            <template #icon><SearchOutlined /></template>
            搜索
          </a-button>
        </template>
      </a-input-search>
    </div>

    <!-- 分类和标签筛选 -->
    <div class="filter-section">
      <a-tabs v-model:active-key="selectedCategory" @change="doSearch" class="custom-tabs">
        <a-tab-pane key="all" tab="全部" />
        <a-tab-pane v-for="category in categoryList" :key="category" :tab="category" />
      </a-tabs>

      <div class="tag-bar">
        <div class="tag-label">标签筛选：</div>
        <a-space :size="[8, 12]" wrap>
          <a-checkable-tag
            v-for="(tag, index) in tagList"
            :key="tag"
            :checked="selectedTagList[index]"
            class="custom-tag"
            @change="
              (checked) => {
                selectedTagList[index] = checked
                doSearch()
              }
            "
          >
            {{ tag }}
          </a-checkable-tag>
        </a-space>
      </div>
    </div>

    <!-- 图片列表 -->
    <PictureList :dataList="dataList" :loading="loading" :hasMore="hasMore" @loadMore="loadMore" />
  </div>
</template>

<script setup lang="ts">
import { onMounted, reactive, ref, onUnmounted } from 'vue'
import {
  listPictureTagCategoryUsingGet,
  listPictureVoByPageUsingPost,
} from '@/api/pictureController.ts'
import { message } from 'ant-design-vue'
import PictureList from '@/components/PictureList.vue' // 定义数据
import { SearchOutlined } from '@ant-design/icons-vue'

// 定义数据
const dataList = ref<API.PictureVO[]>([])
const loading = ref(true)
const hasMore = ref(true)

// 搜索条件
const searchParams = reactive<API.PictureQueryRequest>({
  current: 1,
  pageSize: 12,
  sortField: 'createTime',
  sortOrder: 'descend',
})

// 优化搜索防抖
const debounce = (fn: Function, delay: number) => {
  let timer: NodeJS.Timeout | null = null
  return function (this: any, ...args: any[]) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

// 搜索添加防抖
const doSearch = debounce(() => {
  searchParams.current = 1
  hasMore.value = true
  dataList.value = []
  fetchData()
}, 300)

// 优化数据缓存
const cache = new Map<string, API.PictureVO[]>()

// 获取数据时增加缓存
const fetchData = async (isLoadMore = false) => {
  if (!isLoadMore) {
    loading.value = true
  }

  try {
    const params = {
      ...searchParams,
      tags: [] as string[],
    }
    if (selectedCategory.value !== 'all') {
      params.category = selectedCategory.value
    }
    selectedTagList.value.forEach((useTag, index) => {
      if (useTag) {
        params.tags.push(tagList.value[index])
      }
    })

    // 生成缓存 key
    const cacheKey = JSON.stringify(params)

    // 检查缓存
    if (!isLoadMore && cache.has(cacheKey)) {
      dataList.value = cache.get(cacheKey) ?? []
      loading.value = false
      return
    }

    const res = await listPictureVoByPageUsingPost(params)
    if (res.data.code === 0 && res.data.data) {
      const records = res.data.data.records ?? []
      if (isLoadMore) {
        dataList.value.push(...records)
      } else {
        dataList.value = records
        // 缓存首页数据
        cache.set(cacheKey, records)
      }
      hasMore.value = dataList.value.length < (res.data.data.total ?? 0)
    } else {
      message.error('获取数据失败，' + res.data.message)
    }
  } catch (error) {
    message.error('获取数据失败')
  } finally {
    loading.value = false
  }
}

// 加载更多
const loadMore = () => {
  if (!hasMore.value || loading.value) return
  searchParams.current++
  fetchData(true)
}

// 标签和分类列表
const categoryList = ref<string[]>([])
const selectedCategory = ref<string>('all')
const tagList = ref<string[]>([])
const selectedTagList = ref<boolean[]>([])

/**
 * 获取标签和分类选项
 * @param values
 */
const getTagCategoryOptions = async () => {
  const res = await listPictureTagCategoryUsingGet()
  if (res.data.code === 0 && res.data.data) {
    tagList.value = res.data.data.tagList ?? []
    categoryList.value = res.data.data.categoryList ?? []
  } else {
    message.error('获取标签分类列表失败，' + res.data.message)
  }
}

// 页面加载时获取数据
onMounted(() => {
  getTagCategoryOptions()
  // 添加初始数据加载
  fetchData()
})

// 清理缓存
onUnmounted(() => {
  cache.clear()
})
</script>

<style scoped>
#homePage {
  margin-bottom: 16px;
}

.search-bar {
  max-width: 720px;
  margin: 0 auto 32px;
  text-align: center;
  padding: 32px;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0.9) 100%);
  border-radius: 16px;
  box-shadow:
    0 4px 20px rgba(255, 182, 182, 0.1),
    0 0 0 1px rgba(255, 228, 228, 0.5);
  backdrop-filter: blur(10px);
}

.search-title {
  margin-bottom: 24px;
}

.search-title h1 {
  font-size: 32px;
  font-weight: 600;
  margin-bottom: 8px;
  background: linear-gradient(135deg, #d4463d 0%, #ff6b6b 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  text-shadow: 0 2px 4px rgba(212, 70, 61, 0.1);
}

.search-title .subtitle {
  color: #666;
  font-size: 16px;
  opacity: 0.8;
}

:deep(.ant-input-search) {
  box-shadow: 0 2px 8px rgba(255, 182, 182, 0.1);
}

:deep(.ant-input-search .ant-input) {
  height: 48px;
  font-size: 16px;
  border-color: rgba(255, 228, 228, 0.5);
}

:deep(.ant-input-search .ant-input:hover),
:deep(.ant-input-search .ant-input:focus) {
  border-color: #ff9a9e;
  box-shadow: 0 0 0 2px rgba(255, 154, 158, 0.1);
}

:deep(.ant-btn-primary) {
  height: 48px;
  font-size: 16px;
  padding: 0 24px;
}

.filter-section {
  background: rgba(255, 255, 255, 0.8);
  border-radius: 12px;
  padding: 20px;
  margin-bottom: 24px;
  box-shadow:
    0 2px 12px rgba(255, 182, 182, 0.08),
    0 0 0 1px rgba(255, 228, 228, 0.3);
}

.custom-tabs :deep(.ant-tabs-nav::before) {
  border-bottom-color: rgba(255, 228, 228, 0.3);
}

.custom-tabs :deep(.ant-tabs-tab) {
  padding: 8px 16px;
  transition: all 0.3s;
}

.custom-tabs :deep(.ant-tabs-tab:hover) {
  color: #ff6b6b;
}

.custom-tabs :deep(.ant-tabs-tab-active .ant-tabs-tab-btn) {
  color: #d4463d !important;
  font-weight: 500;
}

.custom-tabs :deep(.ant-tabs-ink-bar) {
  background: #d4463d;
}

.tag-bar {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 228, 228, 0.5);
}

.tag-label {
  color: #666;
  margin-bottom: 12px;
  font-weight: 500;
}

.custom-tag {
  padding: 6px 12px;
  border-radius: 6px;
  border: 1px solid rgba(255, 182, 182, 0.3);
  background: rgba(255, 255, 255, 0.6);
  transition: all 0.3s;
}

.custom-tag:hover {
  border-color: #ff9a9e;
  color: #d4463d;
  transform: translateY(-1px);
}

.custom-tag:global(.ant-tag-checkable-checked) {
  background: linear-gradient(135deg, #ff9a9e 0%, #fad0c4 100%) !important;
  border-color: transparent !important;
  color: #fff !important;
  font-weight: 500;
  box-shadow: 0 2px 6px rgba(255, 154, 158, 0.2);
}
</style>
